﻿/*! ************************************************************
 * \file
 * \brief 线程封装类，具体实现需要继承此类，并实现void run()函数，在run中编写线程处理逻辑。
 *
 * 需要自定义一个class继承Thread，并实现run()函数，在其中进行执行具体逻辑。
 *
 * 逻辑简单的话可以直接用原始方法：std::thread m_thread (函数);
 *
 * \authors 林胜勇
 *
 * \date
 * \verbatim
 * 变更记录：
 * 2023-11-30，林胜勇:
 *   创建文件
 * \endverbatim
 ****************************************************************/
#pragma once

#include <condition_variable>
#include <thread>
#include <vector>

namespace cppc {

class Thread {
public:
    /// 获取当前进程ID
    static unsigned long long currentProcessId();

    /// 获取当前线程ID
    static unsigned long currentThreadId();

    ///  获取当前线程名称
    static std::string currentThreadName();

    /// 设置当前线程名称，最大15个字符，超过的自动截断
    static void setCurrentThreadName(const std::string &name);

    /// 毫秒级休眠
    /// \return 提前结束时，返回剩余时间
    static int sleepMS(long milliseconds);

    /// 秒级休眠
    /// \return 提前结束时，返回剩余时间
    static int sleep(long seconds);

public:
    enum class ThreadState {
        Starting,
        Started,
        Stopping,
        Stopped
    };

public:
    Thread();

    virtual ~Thread();

    std::thread::id id() const;

    /// 获取线程名称
    std::string threadName() const;

    /// 设置线程名称，在调用start()之前设置。最大15个字符，超过的自动截断
    void setThreadName(const std::string &threadName);

    /// 获取线程当前工作状态
    Thread::ThreadState state();

    void start();

    void stop();

    void join();

    void kill();

    /// 线程是否已经运行
    bool isRunning();

private:
    void exec();

protected:
    /// 由子类实现具体线程执行函数
    virtual void run() = 0;

    /// 在调用run前调用willRun
    virtual void willRun();

    /// 调用run后，线程将停止时调用willStop
    virtual void willStop();

protected:
    mutable std::mutex m_mutex;
    ThreadState m_state;
    std::condition_variable m_cond;
    std::thread m_thread;
    /// 线程名称，最大15个字符，超过的自动截断
    std::string m_threadName;
};

} // namespace cppc
